﻿
package extremefx.tools {
	import flash.utils.getQualifiedClassName;

	/**
	 * @author Marcelo Volmaro
	 */
	public final class Overloader {
		private var _methods:Object;
		
		/**
		 * Handy property to start writing overloads using fluent style
		 */
		public static function get define():Overloader {
			return new Overloader();
		}
		
		public function Overloader() {
			_methods = {};
		}
		
		/**
		 * Creates an overloader for the specified method
		 * @param pFunction The method to be called when the overloaded function gets called with the specified argument count/type
		 * @param args The type of the arguments
		 */
		public function method(pFunction:Function, ...args):Overloader {
			_methods[getQualifiedClassNames(args)] = pFunction;
			return this;
		}
		
		/**
		 * Adds the overloaded method applying the overloads over it.
		 */
		public function done():Function {
			return function (...args):* {
				var theF:Function;
				
				if ((theF = _methods[getQualifiedClassNames(args)])) return theF.apply(null, args);
				return null;
			};
		}
		
		private function getQualifiedClassNames(values:Array):String {
            if (values.length == 0) {
                return "_default_";
            }
            
            var classNames:Array = [];
            for each (var value:* in values) {
                classNames.push(getQualifiedClassName(value));
            }
            
            return classNames.join(':');
        }
	}
}